package Gear;

import java.util.ArrayList;
import java.util.concurrent.Semaphore;

/**
 * Class which secure race conditions in local files operations.
 *
 * @author Davi Mendes
 */
public class LocalFileMutex {

    /**
     * Files which are being used by some operation.
     */
    private final ArrayList<String> lockedFiles;

    /**
     * List of semaphores to each files.
     */
    private final ArrayList<Semaphore> fileMutex;

    /**
     * LocalFileMutex constructor.
     */
    public LocalFileMutex() {
        this.lockedFiles = new ArrayList<>();
        this.fileMutex = new ArrayList<>();
    }

    /**
     * Acquire permission to use a file.
     * If the file is already being used, so the thread will block.
     *
     * @param fileName Name of the file to acquire permission.
     */
    public synchronized void acquire(String fileName) {
        try {
            fileMutex.get(lockedFiles.indexOf(fileName)).acquire();
        } catch (IndexOutOfBoundsException ex) {
            lockedFiles.add(fileName);
            fileMutex.add(new Semaphore(0));
        } catch (InterruptedException ex) {
            System.out.println(ex.getMessage());
        }
    }

    /**
     * Release the permission to use a file.
     *
     * @param fileName Name of the file to release permission.
     */
    public synchronized void release(String fileName) {
        int mIndex = lockedFiles.indexOf(fileName);
        Semaphore fMutex = fileMutex.get(mIndex);
        fMutex.release();
        if (fMutex.availablePermits() > 0) {
            lockedFiles.remove(mIndex);
            fileMutex.remove(mIndex);
        }
    }

}
